﻿using System;
using System.Windows;
using System.Windows.Controls;
using Babylon.Toolbox;
using Babylon.Primitives;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Silverlight;
using Microsoft.Xna.Framework.Graphics;
using System.Windows.Media.Imaging;

namespace Babylon.Toolkit.PrimitivesSample
{
    public partial class MainPage
    {
        readonly OrbitCamera _camera;
        readonly ColoredCube _coloredCube;
        VertexColorEffect _coloredCubeEffect;

        readonly TexturedEllipseWithTangents _ellipse;
        BasicEffect _ellipseEffect;

        public MainPage()
        {
            InitializeComponent();
            _camera = new OrbitCamera { Radius = 20 };
            _camera.AttachTo(inputSurface);
            _coloredCube = new ColoredCube(1, 1, 1, new Color(1.0f, .0f, .0f, 1.0f),
                new Color(.0f, 1.0f, .0f, 1.0f),
                new Color(.0f, .0f, 1.0f, 1.0f),
                new Color(1.0f, 1.0f, .0f, 1.0f),
                new Color(1.0f, .0f, 1.0f, 1.0f),
                new Color(.0f, 1.0f, 1.0f, 1.0f),
                new Color(1.0f, 1.0f, 1.0f, 1.0f),
                new Color(.0f, .0f, .0f, 1.0f));

            _ellipse = new TexturedEllipseWithTangents(1, 1.0f, 50);
        }

        private void OnLoaded(object sender, RoutedEventArgs e)
        {
            var gd = GraphicsDeviceManager.Current.GraphicsDevice;
            _coloredCube.Device = gd;
            _coloredCube.LoadContent();
            _coloredCubeEffect = new VertexColorEffect(gd)
            {
                Alpha = 1,
                AmbientColor = new Color(.2f,.2f,.2f,1),
                SceneAmbientColor = new Color(.2f,.2f,.2f,1),
                SpecularPower = 16,
                SpecularColor = new Color(1.0f,1,1,1),                
            };
            _coloredCube.Effect = _coloredCubeEffect;

            _ellipse.Device = gd;
            _ellipse.LoadContent();
            _ellipseEffect = new BasicEffect(gd)
            {
                Alpha = 1,
                AmbientColor = new Color(.2f, .2f, .2f, 1),
                SceneAmbientColor = new Color(.2f, .2f, .2f, 1),
                SpecularPower = 16,
                SpecularColor = new Color(1.0f, 1, 1, 1),
                DiffuseTexture = LoadTexture("EarthDay.png", gd),
                BumpTexture = LoadTexture("EarthNormal.png" ,gd),
                InvertBinormal = true
            };
            _ellipse.Effect = _ellipseEffect;
        }

        static Texture2D LoadTexture(string resource, GraphicsDevice gd)
        {
            var stream = Application.GetResourceStream(new Uri(resource, UriKind.Relative)).Stream;
            var bmp = new BitmapImage();
            bmp.SetSource(stream);


            Texture2D res = new Texture2D(gd, bmp.PixelWidth, bmp.PixelHeight, false, SurfaceFormat.Color);
            bmp.CopyTo(res);
            return res;
        }

        private void OnDraw(object sender, DrawEventArgs e)
        {
            e.GraphicsDevice.Clear(ClearOptions.DepthBuffer | ClearOptions.Target, new Color(0, 0, 0, 1.0f), 1, 0);

            _coloredCube.Device = e.GraphicsDevice;
            _coloredCubeEffect.Device = e.GraphicsDevice;

            _coloredCubeEffect.World = Matrix.CreateTranslation(-5,0,0);
            _coloredCubeEffect.View = _camera.View;
            _coloredCubeEffect.Projection = _camera.Projection;
            _coloredCubeEffect.CameraPosition = _camera.Position;
            _coloredCubeEffect.LightPosition = _camera.Position + new Vector3(1, 5, 3);
            _coloredCube.Draw();


            _ellipse.Device = e.GraphicsDevice;
            _ellipseEffect.Device = e.GraphicsDevice;

            _ellipseEffect.World = Matrix.Identity;
            _ellipseEffect.View = _camera.View;
            _ellipseEffect.Projection = _camera.Projection;
            _ellipseEffect.CameraPosition = _camera.Position;
            _ellipseEffect.LightPosition = _camera.Position + new Vector3(1, 5, 3);
            _ellipse.Draw();

            _camera.ApplyInertia();

            e.InvalidateSurface();
        }

        private void OnSizeChanged(object sender, SizeChangedEventArgs e)
        {
            _camera.AspectRatio = (float)(e.NewSize.Width / e.NewSize.Height);
        }
    }
}
